package cn.mw.cmdb.util;

import java.lang.reflect.Field;
import java.util.Comparator;

public class AlphanumericComparator<T> implements Comparator<T> {
    private final String primaryField;
    private final String secondaryField;
    private final String sortOrder;

    // 构造函数，允许指定主要字段、次要字段和排序方式
    //如果secondaryField不指定，默认使用primaryField排序，sortOrder对其生效
    //如果secondaryField指定，先对secondaryField排序，再primaryField默认使用ASC排序，sortOrder仅对secondaryField生效，
    public AlphanumericComparator(String primaryField, String secondaryField, String sortOrder) {
        this.primaryField = primaryField;
        this.secondaryField = secondaryField;
        this.sortOrder = sortOrder;
    }

    @Override
    public int compare(T o1, T o2) {
        // 如果指定了 secondaryField，优先按 secondaryField 排序
        if (secondaryField != null && !secondaryField.isEmpty()) {
            int secondaryComparison = compareByField(o1, o2, secondaryField);
            if (secondaryComparison != 0) {
                return applySortOrder(secondaryComparison); // 只对 secondaryField 应用 sortOrder
            }
        }

        // 默认按 primaryField 升序排序
        return compareByField(o1, o2, primaryField);
    }

    private int compareByField(T o1, T o2, String fieldName) {
        try {
            Field field = o1.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            Object value1 = field.get(o1);
            Object value2 = field.get(o2);

            if (value1 == null && value2 == null) {
                return 0;
            }
            if (value1 == null) {
                return -1;
            }
            if (value2 == null) {
                return 1;
            }

            // 判断字段是否为数字或字符串
            if (value1 instanceof Number && value2 instanceof Number) {
                return Long.compare(((Number) value1).longValue(), ((Number) value2).longValue());
            } else if (value1 instanceof String && value2 instanceof String) {
                return alphanumericCompare((String) value1, (String) value2);
            } else {
                return value1.toString().compareTo(value2.toString());
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException("Field not found or inaccessible: " + fieldName, e);
        }
    }

    // 仅对 secondaryField 应用 sortOrder
    private int applySortOrder(int comparisonResult) {
        return "DESC".equalsIgnoreCase(sortOrder) ? -comparisonResult : comparisonResult;
    }

    // 对字符串进行字母数字混合排序
    private int alphanumericCompare(String s1, String s2) {
        String[] parts1 = s1.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
        String[] parts2 = s2.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
        int length = Math.min(parts1.length, parts2.length);
        for (int i = 0; i < length; i++) {
            int cmp = compareParts(parts1[i], parts2[i]);
            if (cmp != 0) {
                return cmp;
            }
        }
        return Integer.compare(parts1.length, parts2.length);
    }

    private int compareParts(String part1, String part2) {
        if (isNumber(part1) && isNumber(part2)) {
            return Long.compare(Long.parseLong(part1), Long.parseLong(part2));
        } else {
            return part1.compareTo(part2);
        }
    }

    private boolean isNumber(String str) {
        return str.matches("\\d+");
    }
}

